package com.bwie.service;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bwie.domain.Log;
import com.bwie.domain.Shop;
import com.bwie.domain.Type;
import com.bwie.mapper.LogMapper;
import com.bwie.mapper.ShopMapper;
import com.bwie.mapper.TypeMapper;
import com.bwie.utils.R;
import com.bwie.vo.MessageVo;
import com.bwie.vo.PageInfoVo;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.aspectj.bridge.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.spring.web.json.Json;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Author: lrz
 * @Date: 2024/10/21 10:32
 * @Description:
 **/
@Service
public class ShopServiceImpl implements ShopService {

    @Autowired
    ShopMapper shopMapper;

    @Autowired
    FastFileStorageClient fastFileStorageClient;

    @Autowired
    KafkaTemplate kafkaTemplate;

    @Autowired
    HttpServletRequest httpServletRequest;


    @Autowired
    LogMapper logMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    TypeMapper typeMapper;


    @Override
    public R list(PageInfoVo pageInfoVo) {
        Page<Shop> shopPage = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        if(pageInfoVo.getKeyWord()!=null){
            shopQueryWrapper.lambda().like(Shop::getName,pageInfoVo.getKeyWord());
        }
        Page<Shop> shopPage1 = shopMapper.selectPage(shopPage, shopQueryWrapper);
        return R.OK(shopPage1);
    }

    @Override
    public R addShop(Shop shop) {
        shop.setTime(new Date());
        shopMapper.insert(shop);

        Log log = new Log();
        String token = httpServletRequest.getHeader("token");
        if(token!=null){
            Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
            Integer userId = body.get("userId",Integer.class);
            log.setUserId(userId);
            String userName = body.get("userName", String.class);
            log.setUserName(userName);
        }

        //获取ip
        String ip = httpServletRequest.getRemoteAddr();
        String msgBody = "商品添加："+shop.getName();

        log.setTime(new Date());
        log.setThing(msgBody);
        log.setLogIp(ip);


        //生成消息唯一ID
        String msgId = UUID.randomUUID().toString();
        MessageVo messageVo = new MessageVo();
        messageVo.setMsgId(msgId);
        messageVo.setMsgBody(JSON.toJSONString(log));

        //在发送消息之前,防止消息重复消费
        stringRedisTemplate.opsForValue().set(msgId,JSON.toJSONString(log));


        //发消息
        kafkaTemplate.send("topic-log",JSON.toJSONString(messageVo));

        return R.OK();
    }

    @Override
    public R typeId(Integer id, Integer flag) {
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        shopQueryWrapper.lambda().eq(Shop::getId,id);
        Shop shop = shopMapper.selectById(id);
        if(shop==null){
            return R.ERROR(500,"商品不存在");
        }
        shop.setTypeId(flag);
        shopMapper.updateById(shop);
        return R.OK();
    }

//    图片上传
    @Override
    public R scimg(MultipartFile file) throws IOException {
        //生成文件名
        String originalFilename = file.getOriginalFilename();
        //文件扩展名
        String extName = FileNameUtil.extName(originalFilename);
        //上传文件
        StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), extName, null);
        String url = "http://192.168.80.192:8888/"+storePath.getFullPath();

        return R.OK(url);
    }

    @Override
    public R updateShop(Shop shop) {
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        shopQueryWrapper.lambda().eq(Shop::getId,shop.getId());
        Shop shop1 = shopMapper.selectById(shop);
        if(shop1==null){
            return R.ERROR(500,"商品不存在");
        }
        shopMapper.updateById(shop);
        return R.OK();
    }

    @Override
    public R pdDel(ArrayList<Integer> ids) {
        shopMapper.deleteBatchIds(ids);
        return R.OK();
    }

    @Override
    public List<Shop> getShopList() {
        return shopMapper.selectList(null);
    }

    @Override
    public R typeList() {
        List<Type> types = typeMapper.selectList(null);
        return R.OK(types);
    }

    //    接受消息
    @KafkaListener(topics = "topic-log")
    public void recvMessage(String message, Acknowledgment acknowledgment){
        System.out.println("接收到消息:"+message);

        //解析消息
        MessageVo messageVo = JSON.parseObject(message, MessageVo.class);

        //判断消息是否重复
        Boolean aBoolean = stringRedisTemplate.hasKey(messageVo.getMsgId());
        if(!aBoolean){
            System.out.println("消息重复消费:"+messageVo.getMsgId());
            acknowledgment.acknowledge();
            return;
        }

        //消费消息
        String msgBody = messageVo.getMsgBody();
        Log log = JSON.parseObject(msgBody, Log.class);
        logMapper.insert(log);

        //手动确认消息
        acknowledgment.acknowledge();

        //删除消息的唯一ID
        stringRedisTemplate.delete(messageVo.getMsgId());

        System.out.println("日志消费完毕");
    }

}
